/****************************************************************************
 *  QLyrics - A simple lyrics viewer.                                       *
 *  Copyright (C) 2008  hsys <hanshuiys@gmail.com>                          *
 *                                                                          *
 *  This program is free software; you can redistribute it and/or modify    *
 *  it under the terms of the GNU General Public License as published by    *
 *  the Free Software Foundation; either version 3 of the License, or       *
 *  (at your option) any later version.                                     *
 *                                                                          *
 *  This program is distributed in the hope that it will be useful,         *
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of          *
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
 *  GNU General Public License for more details.                            *
 *                                                                          *
 *  You should have received a copy of the GNU General Public License       *
 *  along with this program; if not, write to the Free Software Foundation, *
 *  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA       *
 ****************************************************************************/

#include "lyricspanel.h"
#include <QTimer>
#include <QPixmap>
#include <QBitmap>
#include <QMouseEvent>
#include "lyricsprovider.h"
#include "configmanager.h"
#include "lyricsmanager.h"

#if defined(_OS_WIN32_) || defined(Q_OS_WIN32)
#include <windows.h>
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "gdi32.lib")
#endif

LyricsPanel::LyricsPanel(QWidget* parent) : QWidget(parent) {
    ConfigManager* cfg = ConfigManager::getInstance();

    setMouseTracking(true);
    m_startTime.start();
    m_trackPlaying = false;

    LyricsPainterManager* panelMgr = LyricsPainterManager::getInstance();
    m_painter = panelMgr->find(cfg->value("Style/ScrollStyle").toString())->create();
    m_painter->setParent(this);
    connect(m_painter, SIGNAL(intervalChanged(int)), SLOT(setInterval(int)));

    // connect signals
    Player* player = Player::getInstance();
    connect(player, SIGNAL(timeChanged(LyricsTime)), SLOT(setPlayerTime(LyricsTime)));
    connect(player, SIGNAL(statusChanged(Player::Status)), SLOT(setPlayerStatus(Player::Status)));

    LyricsManager* mgr = LyricsManager::getInstance();
    connect(mgr, SIGNAL(signalStatusChanged(LyricsProvider::LyricsStatus)),
        SLOT(setLyricsStatus(LyricsProvider::LyricsStatus)));

    m_timer.setInterval(cfg->value("Advanced/MinimalUpdateInterval", 50).toInt());
    connect(&m_timer, SIGNAL(timeout()), SLOT(redraw()));

    // we have to get current player status
    setPlayerTime(player->getPlaybackTime());
    setPlayerStatus(player->getStatus());
    setLyricsStatus(mgr->getStatus());
};

LyricsPanel::~LyricsPanel() {
    //if (m_painter != NULL)
    //    m_painter->deleteLater();
};

void LyricsPanel::setPlayerStatus(Player::Status status) {
    Player* player = Player::getInstance();
    switch (status) {
    case Player::Playing:
        player->updatePlaybackTime();
        m_trackPlaying = true;
        setScrolling(true);
        break;
    case Player::Closed:    // no break here
    case Player::Idle:      // no break here
        m_painter->clearLyrics();
        m_painter->setMessage(tr("No track playing."));
    case Player::Paused:
        m_trackPlaying = false;
        setScrolling(false);
    };
    redraw();
};

/*void LyricsPanel::setLyrics(LyricsData* lyrics) {
    m_painter->setLyrics(lyrics);
};*/

void LyricsPanel::setScrolling(bool isScrolling) {
    if (isScrolling) {
        if (m_painter->canPaintLyrics() && m_trackPlaying)
            m_timer.start();
    } else {
        if (m_timer.isActive())
            m_timer.stop();
    };
};

void LyricsPanel::mousePressEvent(QMouseEvent* e) {
    // just ignore the message and let parent handle it
    e->ignore();
};

void LyricsPanel::mouseMoveEvent(QMouseEvent* e) {
    // just ignore the message and let parent handle it
    e->ignore();
};

void LyricsPanel::mouseReleaseEvent(QMouseEvent* e) {
    // just ignore the message and let parent handle it
    e->ignore();
};

void LyricsPanel::resizeEvent(QResizeEvent *) {
    m_painter->setRect(rect());
    update();
};

void LyricsPanel::setLyricsStatus(LyricsProvider::LyricsStatus status) {
    //Player* player = Player::getInstance();
    LyricsManager* mgr = LyricsManager::getInstance();
    m_painter->clearLyrics();
    switch (status) {
    case LyricsProvider::Success:
        m_painter->setLyrics(mgr->getLyrics());
        // FIXME is this really needed?
        // player->requestTrackTime();
        //if (player->getStatus() == Player::Playing)
        setScrolling(true);
        break;
    case LyricsProvider::Searching:
        m_painter->setMessage(tr("Searching lyrics..."));
        break;
    case LyricsProvider::NotFound:
        m_painter->setMessage(tr("No suitable lyrics found."));
        break;
    case LyricsProvider::NetworkError:
        m_painter->setMessage(tr("Network error."));
        break;
    case LyricsProvider::IOError:
        m_painter->setMessage(tr("I/O error."));
        break;
    case LyricsProvider::Aborted:
        m_painter->setMessage(tr("User aborted."));
        break;
    };
    // FIXME why this?
    //if (status != LyricsProvider::Success) {
    //    m_startTime.start();
    //};
    // Call the virtual function so that sub-classes can implement their own version
    //lyricsChangeEvent(status);
    redraw();
};

void LyricsPanel::setPlayerTime(LyricsTime time) {
    m_startTime.start();
    m_startTime = m_startTime.addMSecs(-time);
    redraw();
};

void LyricsPanel::setInterval(int val) {
    m_timer.setInterval(val);
};
